1Writer 過去タスク検索 + 入力
TaskChute Cloud、TaskChute Cloud 2にはサジェスト機能があり、過去タスクを参照して、その設定をもとにタスクを追加することができた。
1Writer版でも同様のことがやりたいと思い、このコードを書いた。
なお、自分は「サジェスト」というアクション名にしている。
サジェスト機能を使うのが主目的ではあるが、単に過去タスクを検索したいだけの時にも使える。タスクを選択せずにリストを閉じればよい。
タスク行まるごと検索をかけるので、例えば、x (完了タスクに付加される記号) で検索すると、直近の完了タスクを全て表示できる。1日の振り返りなどにも使える。
その他、06:で検索して、6時台の完了タスクだけを取得したりもできる。
機能
1. 過去N日の間のタスクを上限Nタスクに達するまで検索してリスト表示する
2. 選択範囲がある場合は、選択範囲のキーワードで検索、ない場合は入力を求める
3. リストで選択されたタスクのタスク名と見積時間(実績時間を見積時間として設定)を本のファイルのカーソル行の下の行に追加
選択範囲がある場合は選択範囲のキーワードで検索、ない場合は入力を求める処理を追加
code:js
// 過去データ検索
const dayDifference = Math.floor((new Date() - new Date('2024-08-15')) / (1000 * 60 * 60 * 24));
const maxDaysToSearch = dayDifference; // 検索範囲を1ヶ月に制限
const maxTasksToFind = 100; // 検索するタスクの上限を設定
// ノート情報の保存
var cursorPosition = editor.getSelectedRange(); // カーソル位置を保存
const start, end = editor.getSelectedLineRange(); // 現在の選択行の範囲を取得 let originalFilePath; // 元々開いていたファイルのパスを保持
// 検索キーワードを決める(選択範囲があればそれを使用し、なければ入力を求める)
function promptUserForKeywords() {
return new Promise((resolve) => {
const selectedText = editor.getSelectedText(); // 選択されたテキストを取得
if (selectedText) {
resolve(selectedText.split(" ")); // 選択範囲がある場合、そのままキーワードとして使用
} else {
ui.input("タスク検索", "", "検索キーワードを入力してください(スペースで区切るとAND検索)", "default", (input) => {
if (input) {
resolve(input.split(" ")); // スペースで分割してキーワード配列に
} else {
resolve(null); // キャンセルされた場合
}
});
}
});
}
// 指定された日付のノートを開き、その内容を取得する
function getNoteForDate(folderPath, dateString) {
return new Promise((resolve) => {
const filePath = ${folderPath}/${dateString}.md; // 日付ベースのファイル名
editor.openFile(filePath, "edit", (success) => {
if (success) {
const noteText = editor.getText();
resolve(noteText); // ファイルが開けた場合、内容を返す
} else {
resolve(null); // ファイルが開けなかった場合、null を返す
}
});
});
}
// 行がタスクかどうかを判定する関数(タスクは - [x] で始まる)
function isTask(line) {
return line.startsWith("- x "); }
// 行にすべてのキーワードが含まれているかを判定(AND検索)
function containsKeywords(line, keywords) {
return keywords.every(keyword => line.toLowerCase().includes(keyword.toLowerCase()));
}
// 指定フォルダ内でタスクを検索する
async function searchTasks(keywords, folderPath) {
let foundTasks = [];
let currentDate = new Date(); // 現在の日付を取得
let daysChecked = 0;
while (foundTasks.length < maxTasksToFind && daysChecked < maxDaysToSearch) {
// YYYY-MM-DD形式で日付をフォーマット
const dateString = currentDate.toISOString().split('T')0; const note = await getNoteForDate(folderPath, dateString);
if (note) {
const lines = note.split('\n');
for (const line of lines) {
if (isTask(line) && containsKeywords(line, keywords)) {
foundTasks.push({ date: dateString, task: line });
if (foundTasks.length === maxTasksToFind) break;
}
}
}
// 日付を前日に設定
currentDate.setDate(currentDate.getDate() - 1);
daysChecked++;
}
return foundTasks;
}
// タスク行を解析し、開始時刻、終了時刻、実績時間、見積時間、タスク名を抽出する
function parseTaskLine(line) {
// 以下の正規表現を使って、タスクの各要素を抽出
const taskRegex = /^- \x\ (\d{2}:\d{2})-(\d{2}:\d{2})(?:\s+(\d+)?\\?(\d+)?\s+)?(.+)$/; const match = line.match(taskRegex);
if (match) {
return {
startTime: match1 || null, // 開始時刻 endTime: match2 || null, // 終了時刻 actualTime: match3 || null, // 実績時間 estimatedTime: match4 || null, // 見積時間 taskName: match5 ? match5.trim() : "不明" // タスク名 };
} else {
return null; // フォーマットが一致しない場合
}
}
// タスクをリスト形式で表示する
function displayTasks(tasks) {
if (tasks.length === 0) {
ui.hudError("該当するタスクが見つかりませんでした。");
} else {
const taskList = tasks.map(task => {
const parsedTask = parseTaskLine(task.task);
if (parsedTask) {
// タスク名をタイトルとして設定
const title = ${parsedTask.taskName};
const value = \\${parsedTask.actualTime} ${parsedTask.taskName};
// サブタイトル部分を、存在するデータだけで作成
let subtitleParts = [${task.date} ];
if (parsedTask.startTime && parsedTask.endTime) {
subtitleParts.push(${parsedTask.startTime}-${parsedTask.endTime});
}
if (parsedTask.actualTime||parsedTask.estimatedTime) {
subtitleParts.push(' (');
}
if (parsedTask.actualTime) {
subtitleParts.push(${parsedTask.actualTime});
}
// if (parsedTask.estimatedTime) {
// subtitleParts.push(${parsedTask.estimatedTime});
// }
if (parsedTask.actualTime||parsedTask.estimatedTime) {
subtitleParts.push(')');
}
const subtitle = subtitleParts.join('');
return { title, subtitle , value};
} else {
return { title: 不明, subtitle: ${task.date} , value:-}; // 解析できない場合
}
});
ui.list("検索結果", taskList.map(t => ${t.title}|${t.value}|${t.subtitle}), false, (selectedTask) => {
if (selectedTask) {
// 元のノートに戻り、カーソル位置にすべてのタスクを挿入
editor.openFile(originalFilePath, 'edit', function() {
editor.setSelectedRange(end); // カーソル位置に戻る
editor.replaceSelection(\n- [ ] ${selectedTask}); // 選択されたテキストを挿入
editor.setSelectedRange(end + selectedTask.length); // カーソルを挿入後の位置に移動
});
ui.hudSuccess(選択されたタスク: ${selectedTask});
}
});
}
}
// 元々開いていたファイルを再度開く
function reopenOriginalFile() {
if (originalFilePath) {
editor.openFile(originalFilePath, "edit", (success) => {
if (!success) {
ui.hudError("元のファイルを開けませんでした。");
}
});
}
}
// メイン処理
async function main() {
const folderPath = editor.getFolderPath(); // パスを確認して指定する
const filePath = editor.getFileName();
originalFilePath = folderPath + "/" + filePath; // 現在開いているファイルを保存
const keywords = await promptUserForKeywords();
if (!keywords) {
ui.hudError("検索キーワードが入力されませんでした。");
return;
}
// 手動でフォルダパスを指定する(必要に応じて)
const tasks = await searchTasks(keywords, folderPath); // タスクを検索
displayTasks(tasks); // 結果を表示
// 最後に元々開いていたファイルを再度開く
reopenOriginalFile();
}
// 実行
main();
code:js
// 過去データ検索
const maxDaysToSearch = 15; // 検索範囲を1ヶ月に制限
const maxTasksToFind = 30; // 検索するタスクの上限を設定
// ノート情報の保存
var cursorPosition = editor.getSelectedRange(); // カーソル位置を保存
const start, end = editor.getSelectedLineRange(); // 現在の選択行の範囲を取得 let originalFilePath; // 元々開いていたファイルのパスを保持
// 検索キーワードをユーザーに入力させる
function promptUserForKeywords() {
return new Promise((resolve) => {
ui.input("タスク検索", "", "検索キーワードを入力してください(スペースで区切るとAND検索)", "default", (input) => {
if (input) {
resolve(input.split(" ")); // スペースで分割してキーワード配列に
} else {
resolve(null); // キャンセルされた場合
}
});
});
}
// 指定された日付のノートを開き、その内容を取得する
function getNoteForDate(folderPath, dateString) {
return new Promise((resolve) => {
const filePath = ${folderPath}/${dateString}.md; // 日付ベースのファイル名
editor.openFile(filePath, "edit", (success) => {
if (success) {
const noteText = editor.getText();
resolve(noteText); // ファイルが開けた場合、内容を返す
} else {
resolve(null); // ファイルが開けなかった場合、null を返す
}
});
});
}
// 行がタスクかどうかを判定する関数(タスクは - [x] で始まる)
function isTask(line) {
return line.startsWith("- x "); }
// 行にすべてのキーワードが含まれているかを判定(AND検索)
function containsKeywords(line, keywords) {
return keywords.every(keyword => line.toLowerCase().includes(keyword.toLowerCase()));
}
// 指定フォルダ内でタスクを検索する
async function searchTasks(keywords, folderPath) {
let foundTasks = [];
let currentDate = new Date(); // 現在の日付を取得
let daysChecked = 0;
while (foundTasks.length < maxTasksToFind && daysChecked < maxDaysToSearch) {
// YYYY-MM-DD形式で日付をフォーマット
const dateString = currentDate.toISOString().split('T')0; const note = await getNoteForDate(folderPath, dateString);
if (note) {
const lines = note.split('\n');
for (const line of lines) {
if (isTask(line) && containsKeywords(line, keywords)) {
foundTasks.push({ date: dateString, task: line });
if (foundTasks.length === maxTasksToFind) break;
}
}
}
// 日付を前日に設定
currentDate.setDate(currentDate.getDate() - 1);
daysChecked++;
}
return foundTasks;
}
// タスク行を解析し、開始時刻、終了時刻、実績時間、見積時間、タスク名を抽出する
function parseTaskLine(line) {
// 以下の正規表現を使って、タスクの各要素を抽出
const taskRegex = /^- \x\ (\d{2}:\d{2})-(\d{2}:\d{2})(?:\s+(\d+)?\\?(\d+)?\s+)?(.+)$/; const match = line.match(taskRegex);
if (match) {
return {
startTime: match1 || null, // 開始時刻 endTime: match2 || null, // 終了時刻 actualTime: match3 || null, // 実績時間 estimatedTime: match4 || null, // 見積時間 taskName: match5 ? match5.trim() : "不明" // タスク名 };
} else {
return null; // フォーマットが一致しない場合
}
}
// タスクをリスト形式で表示する
function displayTasks(tasks) {
if (tasks.length === 0) {
ui.hudError("該当するタスクが見つかりませんでした。");
} else {
const taskList = tasks.map(task => {
const parsedTask = parseTaskLine(task.task);
if (parsedTask) {
// タスク名をタイトルとして設定
const title = ${parsedTask.taskName};
const value = \\${parsedTask.actualTime} ${parsedTask.taskName};
// サブタイトル部分を、存在するデータだけで作成
let subtitleParts = [${task.date} ];
if (parsedTask.startTime && parsedTask.endTime) {
subtitleParts.push(${parsedTask.startTime}-${parsedTask.endTime});
}
if (parsedTask.actualTime||parsedTask.estimatedTime) {
subtitleParts.push(' (');
}
if (parsedTask.actualTime) {
subtitleParts.push(${parsedTask.actualTime});
}
// if (parsedTask.estimatedTime) {
// subtitleParts.push(${parsedTask.estimatedTime});
// }
if (parsedTask.actualTime||parsedTask.estimatedTime) {
subtitleParts.push(')');
}
const subtitle = subtitleParts.join('');
return { title, subtitle , value};
} else {
return { title: 不明, subtitle: ${task.date} , value:-}; // 解析できない場合
}
});
ui.list("検索結果", taskList.map(t => ${t.title}|${t.value}|${t.subtitle}), false, (selectedTask) => {
if (selectedTask) {
// 元のノートに戻り、カーソル位置にすべてのタスクを挿入
editor.openFile(originalFilePath, 'edit', function() {
editor.setSelectedRange(end); // カーソル位置に戻る
editor.replaceSelection(\n- [ ] ${selectedTask}); // 選択されたテキストを挿入
editor.setSelectedRange(end + selectedTask.length); // カーソルを挿入後の位置に移動
});
ui.hudSuccess(選択されたタスク: ${selectedTask});
}
});
}
}
// 元々開いていたファイルを再度開く
function reopenOriginalFile() {
if (originalFilePath) {
editor.openFile(originalFilePath, "edit", (success) => {
if (!success) {
ui.hudError("元のファイルを開けませんでした。");
}
});
}
}
// メイン処理
async function main() {
const folderPath = editor.getFolderPath(); // パスを確認して指定する
const filePath = editor.getFileName();
originalFilePath = folderPath + "/" + filePath; // 現在開いているファイルを保存
const keywords = await promptUserForKeywords();
if (!keywords) {
ui.hudError("検索キーワードが入力されませんでした。");
return;
}
// 手動でフォルダパスを指定する(必要に応じて)
const tasks = await searchTasks(keywords, folderPath); // タスクを検索
displayTasks(tasks); // 結果を表示
// 最後に元々開いていたファイルを再度開く
reopenOriginalFile();
}
// 実行
main();
カーソル行の下にならない、カーソル位置になる
code:js
// 過去データ検索
const maxDaysToSearch = 15; // 検索範囲を1ヶ月に制限
const maxTasksToFind = 30; // 検索するタスクの上限を設定
// ノート情報の保存
var cursorPosition = editor.getSelectedRange(); // カーソル位置を保存
let originalFilePath; // 元々開いていたファイルのパスを保持
// 検索キーワードをユーザーに入力させる
function promptUserForKeywords() {
return new Promise((resolve) => {
ui.input("タスク検索", "", "検索キーワードを入力してください(スペースで区切るとAND検索)", "default", (input) => {
if (input) {
resolve(input.split(" ")); // スペースで分割してキーワード配列に
} else {
resolve(null); // キャンセルされた場合
}
});
});
}
// 指定された日付のノートを開き、その内容を取得する
function getNoteForDate(folderPath, dateString) {
return new Promise((resolve) => {
const filePath = ${folderPath}/${dateString}.md; // 日付ベースのファイル名
editor.openFile(filePath, "edit", (success) => {
if (success) {
const noteText = editor.getText();
resolve(noteText); // ファイルが開けた場合、内容を返す
} else {
resolve(null); // ファイルが開けなかった場合、null を返す
}
});
});
}
// 行がタスクかどうかを判定する関数(タスクは - [x] で始まる)
function isTask(line) {
return line.startsWith("- x "); }
// 行にすべてのキーワードが含まれているかを判定(AND検索)
function containsKeywords(line, keywords) {
return keywords.every(keyword => line.toLowerCase().includes(keyword.toLowerCase()));
}
// 指定フォルダ内でタスクを検索する
async function searchTasks(keywords, folderPath) {
let foundTasks = [];
let currentDate = new Date(); // 現在の日付を取得
let daysChecked = 0;
while (foundTasks.length < maxTasksToFind && daysChecked < maxDaysToSearch) {
// YYYY-MM-DD形式で日付をフォーマット
const dateString = currentDate.toISOString().split('T')0; const note = await getNoteForDate(folderPath, dateString);
if (note) {
const lines = note.split('\n');
for (const line of lines) {
if (isTask(line) && containsKeywords(line, keywords)) {
foundTasks.push({ date: dateString, task: line });
if (foundTasks.length === maxTasksToFind) break;
}
}
}
// 日付を前日に設定
currentDate.setDate(currentDate.getDate() - 1);
daysChecked++;
}
return foundTasks;
}
// タスク行を解析し、開始時刻、終了時刻、実績時間、見積時間、タスク名を抽出する
function parseTaskLine(line) {
// 以下の正規表現を使って、タスクの各要素を抽出
const taskRegex = /^- \x\ (\d{2}:\d{2})-(\d{2}:\d{2})(?:\s+(\d+)?\\?(\d+)?\s+)?(.+)$/; const match = line.match(taskRegex);
if (match) {
return {
startTime: match1 || null, // 開始時刻 endTime: match2 || null, // 終了時刻 actualTime: match3 || null, // 実績時間 estimatedTime: match4 || null, // 見積時間 taskName: match5 ? match5.trim() : "不明" // タスク名 };
} else {
return null; // フォーマットが一致しない場合
}
}
// タスクをリスト形式で表示する
function displayTasks(tasks) {
if (tasks.length === 0) {
ui.hudError("該当するタスクが見つかりませんでした。");
} else {
const taskList = tasks.map(task => {
const parsedTask = parseTaskLine(task.task);
if (parsedTask) {
// タスク名をタイトルとして設定
const title = ${parsedTask.taskName};
const value = \\${parsedTask.actualTime} ${parsedTask.taskName};
// サブタイトル部分を、存在するデータだけで作成
let subtitleParts = [${task.date} ];
if (parsedTask.startTime && parsedTask.endTime) {
subtitleParts.push(${parsedTask.startTime}-${parsedTask.endTime});
}
if (parsedTask.actualTime||parsedTask.estimatedTime) {
subtitleParts.push(' (');
}
if (parsedTask.actualTime) {
subtitleParts.push(${parsedTask.actualTime});
}
// if (parsedTask.estimatedTime) {
// subtitleParts.push(${parsedTask.estimatedTime});
// }
if (parsedTask.actualTime||parsedTask.estimatedTime) {
subtitleParts.push(')');
}
const subtitle = subtitleParts.join('');
return { title, subtitle , value};
} else {
return { title: 不明, subtitle: ${task.date} , value:-}; // 解析できない場合
}
});
ui.list("検索結果", taskList.map(t => ${t.title}|${t.value}|${t.subtitle}), false, (selectedTask) => {
if (selectedTask) {
// 元のノートに戻り、カーソル位置にすべてのタスクを挿入
editor.openFile(originalFilePath, 'edit', function() {
editor.setSelectedRange(cursorPosition1); // カーソル位置に戻る editor.replaceSelection(\n- [ ] ${selectedTask}); // 選択されたテキストを挿入
editor.setSelectedRange(cursorPosition1 + selectedText.length); // カーソルを挿入後の位置に移動 });
ui.hudSuccess(選択されたタスク: ${selectedTask});
}
});
}
}
// 元々開いていたファイルを再度開く
function reopenOriginalFile() {
if (originalFilePath) {
editor.openFile(originalFilePath, "edit", (success) => {
if (!success) {
ui.hudError("元のファイルを開けませんでした。");
}
});
}
}
// メイン処理
async function main() {
const folderPath = editor.getFolderPath(); // パスを確認して指定する
const filePath = editor.getFileName();
originalFilePath = folderPath + "/" + filePath; // 現在開いているファイルを保存
const keywords = await promptUserForKeywords();
if (!keywords) {
ui.hudError("検索キーワードが入力されませんでした。");
return;
}
// 手動でフォルダパスを指定する(必要に応じて)
const tasks = await searchTasks(keywords, folderPath); // タスクを検索
displayTasks(tasks); // 結果を表示
// 最後に元々開いていたファイルを再度開く
reopenOriginalFile();
}
// 実行
main();
タスク名 見積の順になっている
code:js
// 過去データ検索
const maxDaysToSearch = 15; // 検索範囲を1ヶ月に制限
const maxTasksToFind = 30; // 検索するタスクの上限を設定
// ノート情報の保存
var cursorPosition = editor.getSelectedRange(); // カーソル位置を保存
let originalFilePath; // 元々開いていたファイルのパスを保持
// 検索キーワードをユーザーに入力させる
function promptUserForKeywords() {
return new Promise((resolve) => {
ui.input("タスク検索", "", "検索キーワードを入力してください(スペースで区切るとAND検索)", "default", (input) => {
if (input) {
resolve(input.split(" ")); // スペースで分割してキーワード配列に
} else {
resolve(null); // キャンセルされた場合
}
});
});
}
// 指定された日付のノートを開き、その内容を取得する
function getNoteForDate(folderPath, dateString) {
return new Promise((resolve) => {
const filePath = ${folderPath}/${dateString}.md; // 日付ベースのファイル名
editor.openFile(filePath, "edit", (success) => {
if (success) {
const noteText = editor.getText();
resolve(noteText); // ファイルが開けた場合、内容を返す
} else {
resolve(null); // ファイルが開けなかった場合、null を返す
}
});
});
}
// 行がタスクかどうかを判定する関数(タスクは - [x] で始まる)
function isTask(line) {
return line.startsWith("- x "); }
// 行にすべてのキーワードが含まれているかを判定(AND検索)
function containsKeywords(line, keywords) {
return keywords.every(keyword => line.toLowerCase().includes(keyword.toLowerCase()));
}
// 指定フォルダ内でタスクを検索する
async function searchTasks(keywords, folderPath) {
let foundTasks = [];
let currentDate = new Date(); // 現在の日付を取得
let daysChecked = 0;
while (foundTasks.length < maxTasksToFind && daysChecked < maxDaysToSearch) {
// YYYY-MM-DD形式で日付をフォーマット
const dateString = currentDate.toISOString().split('T')0; const note = await getNoteForDate(folderPath, dateString);
if (note) {
const lines = note.split('\n');
for (const line of lines) {
if (isTask(line) && containsKeywords(line, keywords)) {
foundTasks.push({ date: dateString, task: line });
if (foundTasks.length === maxTasksToFind) break;
}
}
}
// 日付を前日に設定
currentDate.setDate(currentDate.getDate() - 1);
daysChecked++;
}
return foundTasks;
}
// タスク行を解析し、開始時刻、終了時刻、実績時間、見積時間、タスク名を抽出する
function parseTaskLine(line) {
// 以下の正規表現を使って、タスクの各要素を抽出
const taskRegex = /^- \x\ (\d{2}:\d{2})-(\d{2}:\d{2})(?:\s+(\d+)?\\?(\d+)?\s+)?(.+)$/; const match = line.match(taskRegex);
if (match) {
return {
startTime: match1 || null, // 開始時刻 endTime: match2 || null, // 終了時刻 actualTime: match3 || null, // 実績時間 estimatedTime: match4 || null, // 見積時間 taskName: match5 ? match5.trim() : "不明" // タスク名 };
} else {
return null; // フォーマットが一致しない場合
}
}
// タスクをリスト形式で表示する
function displayTasks(tasks) {
if (tasks.length === 0) {
ui.hudError("該当するタスクが見つかりませんでした。");
} else {
const taskList = tasks.map(task => {
const parsedTask = parseTaskLine(task.task);
if (parsedTask) {
// タスク名をタイトルとして設定
const title = ${parsedTask.taskName};
const value = ${parsedTask.taskName} \\${parsedTask.actualTime};
// サブタイトル部分を、存在するデータだけで作成
let subtitleParts = [${task.date} ];
if (parsedTask.startTime && parsedTask.endTime) {
subtitleParts.push(${parsedTask.startTime}-${parsedTask.endTime});
}
if (parsedTask.actualTime||parsedTask.estimatedTime) {
subtitleParts.push(' (');
}
if (parsedTask.actualTime) {
subtitleParts.push(${parsedTask.actualTime});
}
// if (parsedTask.estimatedTime) {
// subtitleParts.push(${parsedTask.estimatedTime});
// }
if (parsedTask.actualTime||parsedTask.estimatedTime) {
subtitleParts.push(')');
}
const subtitle = subtitleParts.join('');
return { title, subtitle , value};
} else {
return { title: 不明, subtitle: ${task.date} , value:-}; // 解析できない場合
}
});
ui.list("検索結果", taskList.map(t => ${t.title}|${t.value}|${t.subtitle}), false, (selectedTask) => {
if (selectedTask) {
// 元のノートに戻り、カーソル位置にすべてのタスクを挿入
editor.openFile(originalFilePath, 'edit', function() {
editor.setSelectedRange(cursorPosition0); // カーソル位置に戻る editor.replaceSelection(\n- [ ] ${selectedTask}); // 選択されたテキストを挿入
editor.setSelectedRange(cursorPosition0 + selectedText.length); // カーソルを挿入後の位置に移動 });
ui.hudSuccess(選択されたタスク: ${selectedTask});
}
});
}
}
// 元々開いていたファイルを再度開く
function reopenOriginalFile() {
if (originalFilePath) {
editor.openFile(originalFilePath, "edit", (success) => {
if (!success) {
ui.hudError("元のファイルを開けませんでした。");
}
});
}
}
// メイン処理
async function main() {
const folderPath = editor.getFolderPath(); // パスを確認して指定する
const filePath = editor.getFileName();
originalFilePath = folderPath + "/" + filePath; // 現在開いているファイルを保存
const keywords = await promptUserForKeywords();
if (!keywords) {
ui.hudError("検索キーワードが入力されませんでした。");
return;
}
// 手動でフォルダパスを指定する(必要に応じて)
const tasks = await searchTasks(keywords, folderPath); // タスクを検索
displayTasks(tasks); // 結果を表示
// 最後に元々開いていたファイルを再度開く
reopenOriginalFile();
}
// 実行
main();
検索自体がうまくいかなくなった。
code:js
// 過去データ検索
const maxDaysToSearch = 15; // 検索範囲を1ヶ月に制限
const maxTasksToFind = 30; // 検索するタスクの上限を設定
// ノート情報の保存
var cursorPosition = editor.getSelectedRange(); // カーソル位置を保存
let originalFilePath; // 元々開いていたファイルのパスを保持
// 検索キーワードをユーザーに入力させる
function promptUserForKeywords() {
return new Promise((resolve) => {
ui.input("タスク検索", "", "検索キーワードを入力してください(スペースで区切るとAND検索)", "default", (input) => {
if (input) {
resolve(input.split(" ")); // スペースで分割してキーワード配列に
} else {
resolve(null); // キャンセルされた場合
}
});
});
}
// 指定された日付のノートを開き、その内容を取得する
function getNoteForDate(folderPath, dateString) {
return new Promise((resolve) => {
const filePath = ${folderPath}/${dateString}.md; // 日付ベースのファイル名
editor.openFile(filePath, "edit", (success) => {
if (success) {
const noteText = editor.getText();
resolve(noteText); // ファイルが開けた場合、内容を返す
} else {
resolve(null); // ファイルが開けなかった場合、null を返す
}
});
});
}
// 行がタスクかどうかを判定する関数(タスクは - [x] で始まる)
function isTask(line) {
return line.startsWith("- x "); }
// 行にすべてのキーワードが含まれているかを判定(AND検索)
function containsKeywords(line, keywords) {
return keywords.every(keyword => line.toLowerCase().includes(keyword.toLowerCase()));
}
// 指定フォルダ内でタスクを検索する
async function searchTasks(keywords, folderPath) {
let foundTasks = [];
let currentDate = new Date(); // 現在の日付を取得
let daysChecked = 0;
while (foundTasks.length < maxTasksToFind && daysChecked < maxDaysToSearch) {
// YYYY-MM-DD形式で日付をフォーマット
const dateString = currentDate.toISOString().split('T')0; const note = await getNoteForDate(folderPath, dateString);
if (note) {
const lines = note.split('\n');
for (const line of lines) {
if (isTask(line) && containsKeywords(line, keywords)) {
foundTasks.push({ date: dateString, task: line });
if (foundTasks.length === maxTasksToFind) break;
}
}
}
// 日付を前日に設定
currentDate.setDate(currentDate.getDate() - 1);
daysChecked++;
}
return foundTasks;
}
// タスク行を解析し、開始時刻、終了時刻、実績時間、見積時間、タスク名を抽出する
function parseTaskLine(line) {
// 以下の正規表現を使って、タスクの各要素を抽出
const taskRegex = /^- \x\ (\d{2}:\d{2})-(\d{2}:\d{2})(?:\s+(\d+)?\\?(\d+)?\s+)?(.+)$/; const match = line.match(taskRegex);
if (match) {
return {
startTime: match1 || null, // 開始時刻 endTime: match2 || null, // 終了時刻 actualTime: match3 || null, // 実績時間 estimatedTime: match4 || null, // 見積時間 taskName: match5 ? match5.trim() : "不明" // タスク名 };
} else {
return null; // フォーマットが一致しない場合
}
}
// タスクをリスト形式で表示する
function displayTasks(tasks) {
if (tasks.length === 0) {
ui.hudError("該当するタスクが見つかりませんでした。");
} else {
const taskList = tasks.map(task => {
const parsedTask = parseTaskLine(task.task);
if (parsedTask) {
// タスク名をタイトルとして設定
const title = ${parsedTask.taskName};
const value = ${parsedTask.taskName} \\${parsedTask.actualTime};
// サブタイトル部分を、存在するデータだけで作成
let subtitleParts = [${task.date} ];
if (parsedTask.startTime && parsedTask.endTime) {
subtitleParts.push(${parsedTask.startTime}-${parsedTask.endTime});
}
if (parsedTask.actualTime||parsedTask.estimatedTime) {
subtitleParts.push(' (');
}
if (parsedTask.actualTime) {
subtitleParts.push(${parsedTask.actualTime});
}
// if (parsedTask.estimatedTime) {
// subtitleParts.push(${parsedTask.estimatedTime});
// }
if (parsedTask.actualTime||parsedTask.estimatedTime) {
subtitleParts.push(')');
}
const subtitle = subtitleParts.join('');
return { title, subtitle , duration};
} else {
return { title: 不明, subtitle: ${task.date} , value:-}; // 解析できない場合
}
});
ui.list("検索結果", taskList.map(t => ${t.title}|${t.value}|${t.subtitle}), false, (selectedTask) => {
if (selectedTask) {
// 元のノートに戻り、カーソル位置にすべてのタスクを挿入
editor.openFile(originalFilePath, 'edit', function() {
editor.setSelectedRange(cursorPosition0); // カーソル位置に戻る editor.replaceSelection(\n- [ ] ${selectedTask}); // 選択されたテキストを挿入
editor.setSelectedRange(cursorPosition0 + selectedText.length); // カーソルを挿入後の位置に移動 });
ui.hudSuccess(選択されたタスク: ${selectedTask});
}
});
}
}
// 元々開いていたファイルを再度開く
function reopenOriginalFile() {
if (originalFilePath) {
editor.openFile(originalFilePath, "edit", (success) => {
if (!success) {
ui.hudError("元のファイルを開けませんでした。");
}
});
}
}
// メイン処理
async function main() {
const folderPath = editor.getFolderPath(); // パスを確認して指定する
const filePath = editor.getFileName();
originalFilePath = folderPath + "/" + filePath; // 現在開いているファイルを保存
const keywords = await promptUserForKeywords();
if (!keywords) {
ui.hudError("検索キーワードが入力されませんでした。");
return;
}
// 手動でフォルダパスを指定する(必要に応じて)
const tasks = await searchTasks(keywords, folderPath); // タスクを検索
displayTasks(tasks); // 結果を表示
// 最後に元々開いていたファイルを再度開く
reopenOriginalFile();
}
// 実行
main();
durationだけが出力される
code:js
// 過去データ検索
const maxDaysToSearch = 15; // 検索範囲を1ヶ月に制限
const maxTasksToFind = 30; // 検索するタスクの上限を設定
// ノート情報の保存
var cursorPosition = editor.getSelectedRange(); // カーソル位置を保存
let originalFilePath; // 元々開いていたファイルのパスを保持
// 検索キーワードをユーザーに入力させる
function promptUserForKeywords() {
return new Promise((resolve) => {
ui.input("タスク検索", "", "検索キーワードを入力してください(スペースで区切るとAND検索)", "default", (input) => {
if (input) {
resolve(input.split(" ")); // スペースで分割してキーワード配列に
} else {
resolve(null); // キャンセルされた場合
}
});
});
}
// 指定された日付のノートを開き、その内容を取得する
function getNoteForDate(folderPath, dateString) {
return new Promise((resolve) => {
const filePath = ${folderPath}/${dateString}.md; // 日付ベースのファイル名
editor.openFile(filePath, "edit", (success) => {
if (success) {
const noteText = editor.getText();
resolve(noteText); // ファイルが開けた場合、内容を返す
} else {
resolve(null); // ファイルが開けなかった場合、null を返す
}
});
});
}
// 行がタスクかどうかを判定する関数(タスクは - [x] で始まる)
function isTask(line) {
return line.startsWith("- x "); }
// 行にすべてのキーワードが含まれているかを判定(AND検索)
function containsKeywords(line, keywords) {
return keywords.every(keyword => line.toLowerCase().includes(keyword.toLowerCase()));
}
// 指定フォルダ内でタスクを検索する
async function searchTasks(keywords, folderPath) {
let foundTasks = [];
let currentDate = new Date(); // 現在の日付を取得
let daysChecked = 0;
while (foundTasks.length < maxTasksToFind && daysChecked < maxDaysToSearch) {
// YYYY-MM-DD形式で日付をフォーマット
const dateString = currentDate.toISOString().split('T')0; const note = await getNoteForDate(folderPath, dateString);
if (note) {
const lines = note.split('\n');
for (const line of lines) {
if (isTask(line) && containsKeywords(line, keywords)) {
foundTasks.push({ date: dateString, task: line });
if (foundTasks.length === maxTasksToFind) break;
}
}
}
// 日付を前日に設定
currentDate.setDate(currentDate.getDate() - 1);
daysChecked++;
}
return foundTasks;
}
// タスク行を解析し、開始時刻、終了時刻、実績時間、見積時間、タスク名を抽出する
function parseTaskLine(line) {
// 以下の正規表現を使って、タスクの各要素を抽出
const taskRegex = /^- \x\ (\d{2}:\d{2})-(\d{2}:\d{2})(?:\s+(\d+)?\\?(\d+)?\s+)?(.+)$/; const match = line.match(taskRegex);
if (match) {
return {
startTime: match1 || null, // 開始時刻 endTime: match2 || null, // 終了時刻 actualTime: match3 || null, // 実績時間 estimatedTime: match4 || null, // 見積時間 taskName: match5 ? match5.trim() : "不明" // タスク名 };
} else {
return null; // フォーマットが一致しない場合
}
}
// タスクをリスト形式で表示する
function displayTasks(tasks) {
if (tasks.length === 0) {
ui.hudError("該当するタスクが見つかりませんでした。");
} else {
const taskList = tasks.map(task => {
const parsedTask = parseTaskLine(task.task);
if (parsedTask) {
// タスク名をタイトルとして設定
const title = ${parsedTask.taskName};
const duration = ${parsedTask.actualTime};
// サブタイトル部分を、存在するデータだけで作成
let subtitleParts = [${task.date} ];
if (parsedTask.startTime && parsedTask.endTime) {
subtitleParts.push(${parsedTask.startTime}-${parsedTask.endTime});
}
if (parsedTask.actualTime||parsedTask.estimatedTime) {
subtitleParts.push(' (');
}
if (parsedTask.actualTime) {
subtitleParts.push(${parsedTask.actualTime});
}
// if (parsedTask.estimatedTime) {
// subtitleParts.push(${parsedTask.estimatedTime});
// }
if (parsedTask.actualTime||parsedTask.estimatedTime) {
subtitleParts.push(')');
}
const subtitle = subtitleParts.join('');
return { title, subtitle , duration};
} else {
return { title: 不明, subtitle: ${task.date} , duration:-}; // 解析できない場合
}
});
ui.list("検索結果", taskList.map(t => ${t.title}|${t.duration}|${t.subtitle}), false, (selectedTask) => {
if (selectedTask) {
// 元のノートに戻り、カーソル位置にすべてのタスクを挿入
editor.openFile(originalFilePath, 'edit', function() {
editor.setSelectedRange(cursorPosition0); // カーソル位置に戻る editor.replaceSelection(\n- [ ] \\10 ${selectedTask}); // 選択されたテキストを挿入
editor.setSelectedRange(cursorPosition0 + selectedText.length); // カーソルを挿入後の位置に移動 });
ui.hudSuccess(選択されたタスク: ${selectedTask});
}
});
}
}
// 元々開いていたファイルを再度開く
function reopenOriginalFile() {
if (originalFilePath) {
editor.openFile(originalFilePath, "edit", (success) => {
if (!success) {
ui.hudError("元のファイルを開けませんでした。");
}
});
}
}
// メイン処理
async function main() {
const folderPath = editor.getFolderPath(); // パスを確認して指定する
const filePath = editor.getFileName();
originalFilePath = folderPath + "/" + filePath; // 現在開いているファイルを保存
const keywords = await promptUserForKeywords();
if (!keywords) {
ui.hudError("検索キーワードが入力されませんでした。");
return;
}
// 手動でフォルダパスを指定する(必要に応じて)
const tasks = await searchTasks(keywords, folderPath); // タスクを検索
displayTasks(tasks); // 結果を表示
// 最後に元々開いていたファイルを再度開く
reopenOriginalFile();
}
// 実行
main();
見積時間が仮値だが、うまくいった
code:js
// 過去データ検索
const maxDaysToSearch = 15; // 検索範囲を1ヶ月に制限
const maxTasksToFind = 30; // 検索するタスクの上限を設定
// ノート情報の保存
var cursorPosition = editor.getSelectedRange(); // カーソル位置を保存
let originalFilePath; // 元々開いていたファイルのパスを保持
// 検索キーワードをユーザーに入力させる
function promptUserForKeywords() {
return new Promise((resolve) => {
ui.input("タスク検索", "", "検索キーワードを入力してください(スペースで区切るとAND検索)", "default", (input) => {
if (input) {
resolve(input.split(" ")); // スペースで分割してキーワード配列に
} else {
resolve(null); // キャンセルされた場合
}
});
});
}
// 指定された日付のノートを開き、その内容を取得する
function getNoteForDate(folderPath, dateString) {
return new Promise((resolve) => {
const filePath = ${folderPath}/${dateString}.md; // 日付ベースのファイル名
editor.openFile(filePath, "edit", (success) => {
if (success) {
const noteText = editor.getText();
resolve(noteText); // ファイルが開けた場合、内容を返す
} else {
resolve(null); // ファイルが開けなかった場合、null を返す
}
});
});
}
// 行がタスクかどうかを判定する関数(タスクは - [x] で始まる)
function isTask(line) {
return line.startsWith("- x "); }
// 行にすべてのキーワードが含まれているかを判定(AND検索)
function containsKeywords(line, keywords) {
return keywords.every(keyword => line.toLowerCase().includes(keyword.toLowerCase()));
}
// 指定フォルダ内でタスクを検索する
async function searchTasks(keywords, folderPath) {
let foundTasks = [];
let currentDate = new Date(); // 現在の日付を取得
let daysChecked = 0;
while (foundTasks.length < maxTasksToFind && daysChecked < maxDaysToSearch) {
// YYYY-MM-DD形式で日付をフォーマット
const dateString = currentDate.toISOString().split('T')0; const note = await getNoteForDate(folderPath, dateString);
if (note) {
const lines = note.split('\n');
for (const line of lines) {
if (isTask(line) && containsKeywords(line, keywords)) {
foundTasks.push({ date: dateString, task: line });
if (foundTasks.length === maxTasksToFind) break;
}
}
}
// 日付を前日に設定
currentDate.setDate(currentDate.getDate() - 1);
daysChecked++;
}
return foundTasks;
}
// タスク行を解析し、開始時刻、終了時刻、実績時間、見積時間、タスク名を抽出する
function parseTaskLine(line) {
// 以下の正規表現を使って、タスクの各要素を抽出
const taskRegex = /^- \x\ (\d{2}:\d{2})-(\d{2}:\d{2})(?:\s+(\d+)?\\?(\d+)?\s+)?(.+)$/; const match = line.match(taskRegex);
if (match) {
return {
startTime: match1 || null, // 開始時刻 endTime: match2 || null, // 終了時刻 actualTime: match3 || null, // 実績時間 estimatedTime: match4 || null, // 見積時間 taskName: match5 ? match5.trim() : "不明" // タスク名 };
} else {
return null; // フォーマットが一致しない場合
}
}
// タスクをリスト形式で表示する
function displayTasks(tasks) {
if (tasks.length === 0) {
ui.hudError("該当するタスクが見つかりませんでした。");
} else {
const taskList = tasks.map(task => {
const parsedTask = parseTaskLine(task.task);
if (parsedTask) {
// タスク名をタイトルとして設定
const title = ${parsedTask.taskName};
// サブタイトル部分を、存在するデータだけで作成
let subtitleParts = [${task.date} ];
if (parsedTask.startTime && parsedTask.endTime) {
subtitleParts.push(${parsedTask.startTime}-${parsedTask.endTime});
}
if (parsedTask.actualTime||parsedTask.estimatedTime) {
subtitleParts.push(' (');
}
if (parsedTask.actualTime) {
subtitleParts.push(${parsedTask.actualTime});
}
// if (parsedTask.estimatedTime) {
// subtitleParts.push(${parsedTask.estimatedTime});
// }
if (parsedTask.actualTime||parsedTask.estimatedTime) {
subtitleParts.push(')');
}
const subtitle = subtitleParts.join('');
return { title, subtitle };
} else {
return { title: 不明, subtitle: ${task.date} }; // 解析できない場合
}
});
ui.list("検索結果", taskList.map(t => ${t.title}||${t.subtitle}), false, (selectedTask) => {
if (selectedTask) {
// 元のノートに戻り、カーソル位置にすべてのタスクを挿入
editor.openFile(originalFilePath, 'edit', function() {
editor.setSelectedRange(cursorPosition0); // カーソル位置に戻る editor.replaceSelection(\n- [ ] \\10 ${selectedTask}); // 選択されたテキストを挿入
editor.setSelectedRange(cursorPosition0 + selectedText.length); // カーソルを挿入後の位置に移動 });
ui.hudSuccess(選択されたタスク: ${selectedTask});
}
});
}
}
// 元々開いていたファイルを再度開く
function reopenOriginalFile() {
if (originalFilePath) {
editor.openFile(originalFilePath, "edit", (success) => {
if (!success) {
ui.hudError("元のファイルを開けませんでした。");
}
});
}
}
// メイン処理
async function main() {
const folderPath = editor.getFolderPath(); // パスを確認して指定する
const filePath = editor.getFileName();
originalFilePath = folderPath + "/" + filePath; // 現在開いているファイルを保存
const keywords = await promptUserForKeywords();
if (!keywords) {
ui.hudError("検索キーワードが入力されませんでした。");
return;
}
// 手動でフォルダパスを指定する(必要に応じて)
const tasks = await searchTasks(keywords, folderPath); // タスクを検索
displayTasks(tasks); // 結果を表示
// 最後に元々開いていたファイルを再度開く
reopenOriginalFile();
}
// 実行
main();f
行後の改行が余計
code:js
// 過去データ検索
const maxDaysToSearch = 15; // 検索範囲を1ヶ月に制限
const maxTasksToFind = 30; // 検索するタスクの上限を設定
// ノート情報の保存
var cursorPosition = editor.getSelectedRange(); // カーソル位置を保存
let originalFilePath; // 元々開いていたファイルのパスを保持
// 検索キーワードをユーザーに入力させる
function promptUserForKeywords() {
return new Promise((resolve) => {
ui.input("タスク検索", "", "検索キーワードを入力してください(スペースで区切るとAND検索)", "default", (input) => {
if (input) {
resolve(input.split(" ")); // スペースで分割してキーワード配列に
} else {
resolve(null); // キャンセルされた場合
}
});
});
}
// 指定された日付のノートを開き、その内容を取得する
function getNoteForDate(folderPath, dateString) {
return new Promise((resolve) => {
const filePath = ${folderPath}/${dateString}.md; // 日付ベースのファイル名
editor.openFile(filePath, "edit", (success) => {
if (success) {
const noteText = editor.getText();
resolve(noteText); // ファイルが開けた場合、内容を返す
} else {
resolve(null); // ファイルが開けなかった場合、null を返す
}
});
});
}
// 行がタスクかどうかを判定する関数(タスクは - [x] で始まる)
function isTask(line) {
return line.startsWith("- x "); }
// 行にすべてのキーワードが含まれているかを判定(AND検索)
function containsKeywords(line, keywords) {
return keywords.every(keyword => line.toLowerCase().includes(keyword.toLowerCase()));
}
// 指定フォルダ内でタスクを検索する
async function searchTasks(keywords, folderPath) {
let foundTasks = [];
let currentDate = new Date(); // 現在の日付を取得
let daysChecked = 0;
while (foundTasks.length < maxTasksToFind && daysChecked < maxDaysToSearch) {
// YYYY-MM-DD形式で日付をフォーマット
const dateString = currentDate.toISOString().split('T')0; const note = await getNoteForDate(folderPath, dateString);
if (note) {
const lines = note.split('\n');
for (const line of lines) {
if (isTask(line) && containsKeywords(line, keywords)) {
foundTasks.push({ date: dateString, task: line });
if (foundTasks.length === maxTasksToFind) break;
}
}
}
// 日付を前日に設定
currentDate.setDate(currentDate.getDate() - 1);
daysChecked++;
}
return foundTasks;
}
// タスク行を解析し、開始時刻、終了時刻、実績時間、見積時間、タスク名を抽出する
function parseTaskLine(line) {
// 以下の正規表現を使って、タスクの各要素を抽出
const taskRegex = /^- \x\ (\d{2}:\d{2})-(\d{2}:\d{2})(?:\s+(\d+)?\\?(\d+)?\s+)?(.+)$/; const match = line.match(taskRegex);
if (match) {
return {
startTime: match1 || null, // 開始時刻 endTime: match2 || null, // 終了時刻 actualTime: match3 || null, // 実績時間 estimatedTime: match4 || null, // 見積時間 taskName: match5 ? match5.trim() : "不明" // タスク名 };
} else {
return null; // フォーマットが一致しない場合
}
}
// タスクをリスト形式で表示する
function displayTasks(tasks) {
if (tasks.length === 0) {
ui.hudError("該当するタスクが見つかりませんでした。");
} else {
const taskList = tasks.map(task => {
const parsedTask = parseTaskLine(task.task);
if (parsedTask) {
// タスク名をタイトルとして設定
const title = ${parsedTask.taskName};
// サブタイトル部分を、存在するデータだけで作成
let subtitleParts = [${task.date} ];
if (parsedTask.startTime && parsedTask.endTime) {
subtitleParts.push(${parsedTask.startTime}-${parsedTask.endTime});
}
if (parsedTask.actualTime||parsedTask.estimatedTime) {
subtitleParts.push(' (');
}
if (parsedTask.actualTime) {
subtitleParts.push(${parsedTask.actualTime});
}
// if (parsedTask.estimatedTime) {
// subtitleParts.push(${parsedTask.estimatedTime});
// }
if (parsedTask.actualTime||parsedTask.estimatedTime) {
subtitleParts.push(')');
}
const subtitle = subtitleParts.join('');
return { title, subtitle };
} else {
return { title: 不明, subtitle: ${task.date} }; // 解析できない場合
}
});
ui.list("検索結果", taskList.map(t => ${t.title}||${t.subtitle}), false, (selectedTask) => {
if (selectedTask) {
// 元のノートに戻り、カーソル位置にすべてのタスクを挿入
editor.openFile(originalFilePath, 'edit', function() {
editor.setSelectedRange(cursorPosition0); // カーソル位置に戻る editor.replaceSelection(\n${selectedTask}\n); // 選択されたテキストを挿入
editor.setSelectedRange(cursorPosition0 + selectedText.length); // カーソルを挿入後の位置に移動 });
ui.hudSuccess(選択されたタスク: ${selectedTask});
}
});
}
}
// 元々開いていたファイルを再度開く
function reopenOriginalFile() {
if (originalFilePath) {
editor.openFile(originalFilePath, "edit", (success) => {
if (!success) {
ui.hudError("元のファイルを開けませんでした。");
}
});
}
}
// メイン処理
async function main() {
const folderPath = editor.getFolderPath(); // パスを確認して指定する
const filePath = editor.getFileName();
originalFilePath = folderPath + "/" + filePath; // 現在開いているファイルを保存
const keywords = await promptUserForKeywords();
if (!keywords) {
ui.hudError("検索キーワードが入力されませんでした。");
return;
}
// 手動でフォルダパスを指定する(必要に応じて)
const tasks = await searchTasks(keywords, folderPath); // タスクを検索
displayTasks(tasks); // 結果を表示
// 最後に元々開いていたファイルを再度開く
reopenOriginalFile();
}
// 実行
main();
エラーになる
code:js
// 過去データ検索
const maxDaysToSearch = 15; // 検索範囲を1ヶ月に制限
const maxTasksToFind = 30; // 検索するタスクの上限を設定
// ノート情報の保存
var cursorPosition = editor.getSelectedRange(); // カーソル位置を保存
let originalFilePath; // 元々開いていたファイルのパスを保持
// 検索キーワードをユーザーに入力させる
function promptUserForKeywords() {
return new Promise((resolve) => {
ui.input("タスク検索", "", "検索キーワードを入力してください(スペースで区切るとAND検索)", "default", (input) => {
if (input) {
resolve(input.split(" ")); // スペースで分割してキーワード配列に
} else {
resolve(null); // キャンセルされた場合
}
});
});
}
// 指定された日付のノートを開き、その内容を取得する
function getNoteForDate(folderPath, dateString) {
return new Promise((resolve) => {
const filePath = ${folderPath}/${dateString}.md; // 日付ベースのファイル名
editor.openFile(filePath, "edit", (success) => {
if (success) {
const noteText = editor.getText();
resolve(noteText); // ファイルが開けた場合、内容を返す
} else {
resolve(null); // ファイルが開けなかった場合、null を返す
}
});
});
}
// 行がタスクかどうかを判定する関数(タスクは - [x] で始まる)
function isTask(line) {
return line.startsWith("- x "); }
// 行にすべてのキーワードが含まれているかを判定(AND検索)
function containsKeywords(line, keywords) {
return keywords.every(keyword => line.toLowerCase().includes(keyword.toLowerCase()));
}
// 指定フォルダ内でタスクを検索する
async function searchTasks(keywords, folderPath) {
let foundTasks = [];
let currentDate = new Date(); // 現在の日付を取得
let daysChecked = 0;
while (foundTasks.length < maxTasksToFind && daysChecked < maxDaysToSearch) {
// YYYY-MM-DD形式で日付をフォーマット
const dateString = currentDate.toISOString().split('T')0; const note = await getNoteForDate(folderPath, dateString);
if (note) {
const lines = note.split('\n');
for (const line of lines) {
if (isTask(line) && containsKeywords(line, keywords)) {
foundTasks.push({ date: dateString, task: line });
if (foundTasks.length === maxTasksToFind) break;
}
}
}
// 日付を前日に設定
currentDate.setDate(currentDate.getDate() - 1);
daysChecked++;
}
return foundTasks;
}
// タスク行を解析し、開始時刻、終了時刻、実績時間、見積時間、タスク名を抽出する
function parseTaskLine(line) {
// 以下の正規表現を使って、タスクの各要素を抽出
const taskRegex = /^- \x\ (\d{2}:\d{2})-(\d{2}:\d{2})(?:\s+(\d+)?\\?(\d+)?\s+)?(.+)$/; const match = line.match(taskRegex);
if (match) {
return {
startTime: match1 || null, // 開始時刻 endTime: match2 || null, // 終了時刻 actualTime: match3 || null, // 実績時間 estimatedTime: match4 || null, // 見積時間 taskName: match5 ? match5.trim() : "不明" // タスク名 };
} else {
return null; // フォーマットが一致しない場合
}
}
// タスクをリスト形式で表示する
function displayTasks(tasks) {
if (tasks.length === 0) {
ui.hudError("該当するタスクが見つかりませんでした。");
} else {
const taskList = tasks.map(task => {
const parsedTask = parseTaskLine(task.task);
if (parsedTask) {
// タスク名をタイトルとして設定
const title = ${parsedTask.taskName};
// サブタイトル部分を、存在するデータだけで作成
let subtitleParts = [${task.date} ];
if (parsedTask.startTime && parsedTask.endTime) {
subtitleParts.push(${parsedTask.startTime}-${parsedTask.endTime});
}
if (parsedTask.actualTime||parsedTask.estimatedTime) {
subtitleParts.push(' (');
}
if (parsedTask.actualTime) {
subtitleParts.push(${parsedTask.actualTime});
}
// if (parsedTask.estimatedTime) {
// subtitleParts.push(${parsedTask.estimatedTime});
// }
if (parsedTask.actualTime||parsedTask.estimatedTime) {
subtitleParts.push(')');
}
const subtitle = subtitleParts.join('');
return { title, subtitle };
} else {
return { title: 不明, subtitle: ${task.date} }; // 解析できない場合
}
});
ui.list("検索結果", taskList.map(t => ${t.title}||${t.subtitle}), false, (selectedTask) => {
if (selectedTask) {
// 元のノートに戻り、カーソル位置にすべてのタスクを挿入
editor.openFile(originalFilePath, 'edit', function() {
editor.setSelectedRange(cursorPosition0); // カーソル位置に戻る editor.replaceSelection(${selectedTask}\n); // 選択されたテキストを挿入
editor.setSelectedRange(cursorPosition0 + selectedText.length + 1); // カーソルを挿入後の位置に移動 });
ui.hudSuccess(選択されたタスク: ${selectedTask});
}
});
}
}
// 元々開いていたファイルを再度開く
function reopenOriginalFile() {
if (originalFilePath) {
editor.openFile(originalFilePath, "edit", (success) => {
if (!success) {
ui.hudError("元のファイルを開けませんでした。");
}
});
}
}
// メイン処理
async function main() {
const folderPath = editor.getFolderPath(); // パスを確認して指定する
const filePath = editor.getFileName();
originalFilePath = folderPath + "/" + filePath; // 現在開いているファイルを保存
const keywords = await promptUserForKeywords();
if (!keywords) {
ui.hudError("検索キーワードが入力されませんでした。");
return;
}
// 手動でフォルダパスを指定する(必要に応じて)
const tasks = await searchTasks(keywords, folderPath); // タスクを検索
displayTasks(tasks); // 結果を表示
// 最後に元々開いていたファイルを再度開く
reopenOriginalFile();
}
// 実行
main();
選択行の末尾
タスク名のみ
code:js
// 過去データ検索
const maxDaysToSearch = 15; // 検索範囲を1ヶ月に制限
const maxTasksToFind = 30; // 検索するタスクの上限を設定
// ノート情報の保存
var cursorPosition = editor.getSelectedRange(); // カーソル位置を保存
let originalFilePath; // 元々開いていたファイルのパスを保持
// 検索キーワードをユーザーに入力させる
function promptUserForKeywords() {
return new Promise((resolve) => {
ui.input("タスク検索", "", "検索キーワードを入力してください(スペースで区切るとAND検索)", "default", (input) => {
if (input) {
resolve(input.split(" ")); // スペースで分割してキーワード配列に
} else {
resolve(null); // キャンセルされた場合
}
});
});
}
// 指定された日付のノートを開き、その内容を取得する
function getNoteForDate(folderPath, dateString) {
return new Promise((resolve) => {
const filePath = ${folderPath}/${dateString}.md; // 日付ベースのファイル名
editor.openFile(filePath, "edit", (success) => {
if (success) {
const noteText = editor.getText();
resolve(noteText); // ファイルが開けた場合、内容を返す
} else {
resolve(null); // ファイルが開けなかった場合、null を返す
}
});
});
}
// 行がタスクかどうかを判定する関数(タスクは - [x] で始まる)
function isTask(line) {
return line.startsWith("- x "); }
// 行にすべてのキーワードが含まれているかを判定(AND検索)
function containsKeywords(line, keywords) {
return keywords.every(keyword => line.toLowerCase().includes(keyword.toLowerCase()));
}
// 指定フォルダ内でタスクを検索する
async function searchTasks(keywords, folderPath) {
let foundTasks = [];
let currentDate = new Date(); // 現在の日付を取得
let daysChecked = 0;
while (foundTasks.length < maxTasksToFind && daysChecked < maxDaysToSearch) {
// YYYY-MM-DD形式で日付をフォーマット
const dateString = currentDate.toISOString().split('T')0; const note = await getNoteForDate(folderPath, dateString);
if (note) {
const lines = note.split('\n');
for (const line of lines) {
if (isTask(line) && containsKeywords(line, keywords)) {
foundTasks.push({ date: dateString, task: line });
if (foundTasks.length === maxTasksToFind) break;
}
}
}
// 日付を前日に設定
currentDate.setDate(currentDate.getDate() - 1);
daysChecked++;
}
return foundTasks;
}
// タスク行を解析し、開始時刻、終了時刻、実績時間、見積時間、タスク名を抽出する
function parseTaskLine(line) {
// 以下の正規表現を使って、タスクの各要素を抽出
const taskRegex = /^- \x\ (\d{2}:\d{2})-(\d{2}:\d{2})(?:\s+(\d+)?\\?(\d+)?\s+)?(.+)$/; const match = line.match(taskRegex);
if (match) {
return {
startTime: match1 || null, // 開始時刻 endTime: match2 || null, // 終了時刻 actualTime: match3 || null, // 実績時間 estimatedTime: match4 || null, // 見積時間 taskName: match5 ? match5.trim() : "不明" // タスク名 };
} else {
return null; // フォーマットが一致しない場合
}
}
// タスクをリスト形式で表示する
function displayTasks(tasks) {
if (tasks.length === 0) {
ui.hudError("該当するタスクが見つかりませんでした。");
} else {
const taskList = tasks.map(task => {
const parsedTask = parseTaskLine(task.task);
if (parsedTask) {
// タスク名をタイトルとして設定
const title = ${parsedTask.taskName};
// サブタイトル部分を、存在するデータだけで作成
let subtitleParts = [${task.date} ];
if (parsedTask.startTime && parsedTask.endTime) {
subtitleParts.push(${parsedTask.startTime}-${parsedTask.endTime});
}
if (parsedTask.actualTime||parsedTask.estimatedTime) {
subtitleParts.push(' (');
}
if (parsedTask.actualTime) {
subtitleParts.push(${parsedTask.actualTime});
}
// if (parsedTask.estimatedTime) {
// subtitleParts.push(${parsedTask.estimatedTime});
// }
if (parsedTask.actualTime||parsedTask.estimatedTime) {
subtitleParts.push(')');
}
const subtitle = subtitleParts.join('');
return { title, subtitle };
} else {
return { title: 不明, subtitle: ${task.date} }; // 解析できない場合
}
});
ui.list("検索結果", taskList.map(t => ${t.title}||${t.subtitle}), false, (selectedTask) => {
if (selectedTask) {
// 元のノートに戻り、カーソル位置にすべてのタスクを挿入
editor.openFile(originalFilePath, 'edit', function() {
editor.setSelectedRange(cursorPosition0); // カーソル位置に戻る editor.replaceSelection(${selectedTask}); // 選択されたテキストを挿入
editor.setSelectedRange(cursorPosition0 + selectedText.length); // カーソルを挿入後の位置に移動 });
ui.hudSuccess(選択されたタスク: ${selectedTask});
}
});
}
}
// 元々開いていたファイルを再度開く
function reopenOriginalFile() {
if (originalFilePath) {
editor.openFile(originalFilePath, "edit", (success) => {
if (!success) {
ui.hudError("元のファイルを開けませんでした。");
}
});
}
}
// メイン処理
async function main() {
const folderPath = editor.getFolderPath(); // パスを確認して指定する
const filePath = editor.getFileName();
originalFilePath = folderPath + "/" + filePath; // 現在開いているファイルを保存
const keywords = await promptUserForKeywords();
if (!keywords) {
ui.hudError("検索キーワードが入力されませんでした。");
return;
}
// 手動でフォルダパスを指定する(必要に応じて)
const tasks = await searchTasks(keywords, folderPath); // タスクを検索
displayTasks(tasks); // 結果を表示
// 最後に元々開いていたファイルを再度開く
reopenOriginalFile();
}
// 実行
main();
code:js
// 過去データ検索
const maxDaysToSearch = 15; // 検索範囲を1ヶ月に制限
const maxTasksToFind = 30; // 検索するタスクの上限を設定
// ノート情報の保存
var cursorPosition = editor.getSelectedRange(); // カーソル位置を保存
let originalFilePath; // 元々開いていたファイルのパスを保持
// 検索キーワードをユーザーに入力させる
function promptUserForKeywords() {
return new Promise((resolve) => {
ui.input("タスク検索", "", "検索キーワードを入力してください(スペースで区切るとAND検索)", "default", (input) => {
if (input) {
resolve(input.split(" ")); // スペースで分割してキーワード配列に
} else {
resolve(null); // キャンセルされた場合
}
});
});
}
// 指定された日付のノートを開き、その内容を取得する
function getNoteForDate(folderPath, dateString) {
return new Promise((resolve) => {
const filePath = ${folderPath}/${dateString}.md; // 日付ベースのファイル名
editor.openFile(filePath, "edit", (success) => {
if (success) {
const noteText = editor.getText();
resolve(noteText); // ファイルが開けた場合、内容を返す
} else {
resolve(null); // ファイルが開けなかった場合、null を返す
}
});
});
}
// 行がタスクかどうかを判定する関数(タスクは - [x] で始まる)
function isTask(line) {
return line.startsWith("- x "); }
// 行にすべてのキーワードが含まれているかを判定(AND検索)
function containsKeywords(line, keywords) {
return keywords.every(keyword => line.toLowerCase().includes(keyword.toLowerCase()));
}
// 指定フォルダ内でタスクを検索する
async function searchTasks(keywords, folderPath) {
let foundTasks = [];
let currentDate = new Date(); // 現在の日付を取得
let daysChecked = 0;
while (foundTasks.length < maxTasksToFind && daysChecked < maxDaysToSearch) {
// YYYY-MM-DD形式で日付をフォーマット
const dateString = currentDate.toISOString().split('T')0; const note = await getNoteForDate(folderPath, dateString);
if (note) {
const lines = note.split('\n');
for (const line of lines) {
if (isTask(line) && containsKeywords(line, keywords)) {
foundTasks.push({ date: dateString, task: line });
if (foundTasks.length === maxTasksToFind) break;
}
}
}
// 日付を前日に設定
currentDate.setDate(currentDate.getDate() - 1);
daysChecked++;
}
return foundTasks;
}
// タスク行を解析し、開始時刻、終了時刻、実績時間、見積時間、タスク名を抽出する
function parseTaskLine(line) {
// 以下の正規表現を使って、タスクの各要素を抽出
const taskRegex = /^- \x\ (\d{2}:\d{2})-(\d{2}:\d{2})(?:\s+(\d+)?\\?(\d+)?\s+)?(.+)$/; const match = line.match(taskRegex);
if (match) {
return {
startTime: match1 || null, // 開始時刻 endTime: match2 || null, // 終了時刻 actualTime: match3 || null, // 実績時間 estimatedTime: match4 || null, // 見積時間 taskName: match5 ? match5.trim() : "不明" // タスク名 };
} else {
return null; // フォーマットが一致しない場合
}
}
// タスクをリスト形式で表示する
function displayTasks(tasks) {
if (tasks.length === 0) {
ui.hudError("該当するタスクが見つかりませんでした。");
} else {
const taskList = tasks.map(task => {
const parsedTask = parseTaskLine(task.task);
if (parsedTask) {
// タスク名をタイトルとして設定
const title = ${parsedTask.taskName};
// サブタイトル部分を、存在するデータだけで作成
let subtitleParts = [${task.date} ];
if (parsedTask.startTime && parsedTask.endTime) {
subtitleParts.push(${parsedTask.startTime}-${parsedTask.endTime});
}
if (parsedTask.actualTime||parsedTask.estimatedTime) {
subtitleParts.push(' (');
}
if (parsedTask.actualTime) {
subtitleParts.push(${parsedTask.actualTime});
}
// if (parsedTask.estimatedTime) {
// subtitleParts.push(${parsedTask.estimatedTime});
// }
if (parsedTask.actualTime||parsedTask.estimatedTime) {
subtitleParts.push(')');
}
const subtitle = subtitleParts.join('');
return { title, subtitle };
} else {
return { title: 不明, subtitle: ${task.date} }; // 解析できない場合
}
});
ui.list("検索結果", taskList.map(t => ${t.title}||${t.subtitle}), false, (selectedTask) => {
if (selectedTask) {
// 元のノートに戻り、カーソル位置にすべてのタスクを挿入
editor.openFile(originalFilePath, 'edit', function() {
editor.setSelectedRange(cursorPosition0); // カーソル位置に戻る editor.replaceSelection(selectedText); // 選択されたテキストを挿入
editor.setSelectedRange(cursorPosition0 + selectedText.length); // カーソルを挿入後の位置に移動 });
ui.hudSuccess(選択されたタスク: ${selectedTask});
}
});
}
}
// 元々開いていたファイルを再度開く
function reopenOriginalFile() {
if (originalFilePath) {
editor.openFile(originalFilePath, "edit", (success) => {
if (!success) {
ui.hudError("元のファイルを開けませんでした。");
}
});
}
}
// メイン処理
async function main() {
const folderPath = editor.getFolderPath(); // パスを確認して指定する
const filePath = editor.getFileName();
originalFilePath = folderPath + "/" + filePath; // 現在開いているファイルを保存
const keywords = await promptUserForKeywords();
if (!keywords) {
ui.hudError("検索キーワードが入力されませんでした。");
return;
}
// 手動でフォルダパスを指定する(必要に応じて)
const tasks = await searchTasks(keywords, folderPath); // タスクを検索
displayTasks(tasks); // 結果を表示
// 最後に元々開いていたファイルを再度開く
reopenOriginalFile();
}
// 実行
main();